package com.cskaoyan.market.service.admin;

import com.cskaoyan.market.bo.MarketGoodsBo;
import com.cskaoyan.market.db.domain.*;
import com.cskaoyan.market.db.mapper.*;
import com.cskaoyan.market.vo.CatAndBrandVo;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class MarketGoodsServiceImpl implements MarketGoodsService {
    @Autowired
    MarketGoodsMapper marketGoodsMapper;

    @Autowired
    MarketCategoryMapper marketCategoryMapper;

    @Autowired
    MarketBrandMapper marketBrandMapper;

    @Autowired
    MarketGoodsSpecificationMapper marketGoodsSpecificationMapper;

    @Autowired
    MarketGoodsProductMapper marketGoodsProductMapper;

    @Autowired
    MarketGoodsAttributeMapper marketGoodsAttributeMapper;

    @Override
    public List<MarketGoods> list(Integer page, Integer limit, String goodsSn, String name, String sort, String order, String goodsId) {
        //使用mybatis去数据库中查询数据
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        marketGoodsExample.setOrderByClause(sort + " " + order);
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        if (!StringUtils.isEmpty(goodsId)) {
            criteria.andIdEqualTo(Integer.parseInt(goodsId));
        }
        if (!StringUtils.isEmpty(goodsSn)) {
            criteria.andGoodsSnLike("%" + goodsSn + "%");
        }
        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        PageHelper.startPage(page, limit);
        List<MarketGoods> marketGoodsList = marketGoodsMapper.selectByExample(marketGoodsExample);
        return marketGoodsList;
    }

    @Override
    public Map<String, Object> catAndBrand() {
        //查询category和brand两张表
        List<MarketCategory> categories = marketCategoryMapper.selectByExample(new MarketCategoryExample());
        List<MarketBrand> brands = marketBrandMapper.selectByExample(new MarketBrandExample());
        //保存返回信息
        Map<String, Object> result = new HashMap<>();
        List<CatAndBrandVo> brandList = new ArrayList<>();
        List<CatAndBrandVo> categoryList = new ArrayList<>();
        //categoryList的数据同样需要通过pid进行分组，与region中的方法类似，通过map分组，key为pid，value为有当前pid的所有对象
        Map<Integer, List<MarketCategory>> categoriesByPid = groupByPid(categories);
        //先获取一级类目
        List<MarketCategory> l1Categories = categoriesByPid.get(0);
        for (MarketCategory l1 : l1Categories) {
            List<CatAndBrandVo> children = new ArrayList<>();
            CatAndBrandVo l1Vo = new CatAndBrandVo(l1.getName(), l1.getId(), children);
            categoryList.add(l1Vo);
            List<MarketCategory> l2Categories = categoriesByPid.get(l1.getId());
            if (l2Categories != null) {
                for (MarketCategory l2 : l2Categories) {
                    children.add(new CatAndBrandVo(l2.getName(), l2.getId(), null));
                }
            }
        }
        for (MarketBrand brand : brands) {
            brandList.add(new CatAndBrandVo(brand.getName(), brand.getId(), null));
        }
        result.put("brandList", brandList);
        result.put("categoryList", categoryList);
        return result;
    }

    @Transactional
    @Override
    public void create(MarketGoods goods, List<MarketGoodsProduct> products, List<MarketGoodsSpecification> specifications, List<MarketGoodsAttribute> attributes) {
        //首先插入goods表
        //零售价格---所有规格中较低的一个价格
        //获取所有的货品价格，取一个较低的价格
        //在外部设置一个较大的变量，如果遇到小值，则更新；取index=0下标的；如果后续遇到小值，也是更新
        BigDecimal price = products.get(0).getPrice();
        for (int i = 1; i < products.size(); i++) {
            //如果后续出现了一个更小的值，则更新price的值
            BigDecimal decimal = products.get(i).getPrice();
            if (price.compareTo(decimal) == 1) {
                //表示price 大于decimal的值，出现更小值，则把更小的值赋值给price
                price = decimal;
            }
        }
        goods.setRetailPrice(price);
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goods.setDeleted(false);
        //最终要保障事务
        marketGoodsMapper.insertSelective(goods);
        Integer id = goods.getId();
        //插入规格
        //对于另外三张表来说，需要goods的编号，怎么获取goods的编号？？？？？goods.getId即可
        for (MarketGoodsSpecification sp : specifications) {
            sp.setGoodsId(id);
            sp.setAddTime(LocalDateTime.now());
            sp.setUpdateTime(LocalDateTime.now());
            sp.setDeleted(false);
            marketGoodsSpecificationMapper.insertSelective(sp);
        }
        for (MarketGoodsProduct product : products) {
            product.setGoodsId(id);
            product.setAddTime(LocalDateTime.now());
            product.setUpdateTime(LocalDateTime.now());
            product.setDeleted(false);
            marketGoodsProductMapper.insertSelective(product);
        }
        for (MarketGoodsAttribute attribute : attributes) {
            attribute.setGoodsId(id);
            attribute.setAddTime(LocalDateTime.now());
            attribute.setUpdateTime(LocalDateTime.now());
            attribute.setDeleted(false);
            marketGoodsAttributeMapper.insertSelective(attribute);
        }

    }

    @Override
    public void update(MarketGoods goods, List<MarketGoodsProduct> products, List<MarketGoodsSpecification> specifications, List<MarketGoodsAttribute> attributes) {

        //每更新一条都设置更新时间，如果之前为空，后来添加了，则插入
        goods.setUpdateTime(LocalDateTime.now());
        Integer id = goods.getId();
        marketGoodsMapper.updateByPrimaryKeySelective(goods);
        for (MarketGoodsProduct product : products) {
            product.setUpdateTime(LocalDateTime.now());
            product.setDeleted(false);
            marketGoodsProductMapper.updateByPrimaryKeySelective(product);
        }
        for (MarketGoodsSpecification specification : specifications) {
            specification.setUpdateTime(LocalDateTime.now());
            specification.setDeleted(false);
            marketGoodsSpecificationMapper.updateByPrimaryKeySelective(specification);
        }
        //attribute可能有新添加的项，如果原来未创建过，则改为新增
        for (MarketGoodsAttribute attribute : attributes) {
            attribute.setUpdateTime(LocalDateTime.now());
            //判断是否是新增的条目，是则插入，不是则更新时间
            MarketGoodsAttribute marketGoodsAttribute = marketGoodsAttributeMapper.selectByPrimaryKey(attribute.getId());
            if (marketGoodsAttribute == null) {
                attribute.setAddTime(LocalDateTime.now());
                attribute.setGoodsId(id);
                attribute.setDeleted(false);
                marketGoodsAttributeMapper.insert(attribute);
            }
            else {
                marketGoodsAttributeMapper.updateByPrimaryKey(attribute);
            }
        }

    }

    @Override
    public Map<String, Object> detail(Integer goodsId) {
        MarketGoodsBo marketGoodsBo = new MarketGoodsBo();
        Map<String, Object> result = new HashMap<>();
        //goods
        MarketGoodsExample goodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria goodsExampleCriteria = goodsExample.createCriteria();
        goodsExampleCriteria.andIdEqualTo(goodsId);
        MarketGoods marketGoods = marketGoodsMapper.selectOneByExampleWithBLOBs(goodsExample);
        marketGoodsBo.setGoods(marketGoods);
        //categoryIds
        List<Integer> categoryIds = null;
        Integer categoryId = marketGoods.getCategoryId();
        MarketCategory marketCategory = marketCategoryMapper.selectByPrimaryKey(categoryId);
        if (marketCategory != null) {
            categoryIds = Arrays.asList(marketCategory.getPid(), categoryId);
        }
        //productList
        MarketGoodsProductExample marketGoodsProductExample = new MarketGoodsProductExample();
        MarketGoodsProductExample.Criteria criteria = marketGoodsProductExample.createCriteria();
        criteria.andGoodsIdEqualTo(goodsId);
        List<MarketGoodsProduct> productList = marketGoodsProductMapper.selectByExample(marketGoodsProductExample);
        //specificationList
        MarketGoodsSpecificationExample marketGoodsSpecificationExample = new MarketGoodsSpecificationExample();
        MarketGoodsSpecificationExample.Criteria specificationExampleCriteria = marketGoodsSpecificationExample.createCriteria();
        specificationExampleCriteria.andGoodsIdEqualTo(goodsId);
        List<MarketGoodsSpecification> specificationList = marketGoodsSpecificationMapper.selectByExample(marketGoodsSpecificationExample);
        //attributeList
        MarketGoodsAttributeExample marketGoodsAttributeExample = new MarketGoodsAttributeExample();
        MarketGoodsAttributeExample.Criteria attributeExampleCriteria = marketGoodsAttributeExample.createCriteria();
        attributeExampleCriteria.andGoodsIdEqualTo(goodsId);
        List<MarketGoodsAttribute> attributeList = marketGoodsAttributeMapper.selectByExample(marketGoodsAttributeExample);
        result.put("goods", marketGoods);
        result.put("categoryIds", categoryIds);
        result.put("attributes", attributeList);
        result.put("products", productList);
        result.put("specifications", specificationList);
        return result;
    }

    @Override
    public void delete(MarketGoods goods) {
        marketGoodsMapper.deleteByPrimaryKey(goods.getId());
    }


    private Map<Integer, List<MarketCategory>> groupByPid(List<MarketCategory> categories) {
        Map<Integer, List<MarketCategory>> result = new HashMap<>();
        for (MarketCategory category : categories) {
            Integer pid = category.getPid();
            List<MarketCategory> marketCategoryList = result.get(pid);
            if (marketCategoryList == null) {
                marketCategoryList = new ArrayList<>();
            }
            marketCategoryList.add(category);
            result.put(pid, marketCategoryList);
        }
        return result;
    }


}

